package com.kadron.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

import org.hibernate.validator.NotNull;

import com.kadron.account.AccountData;
import com.kadron.base.KVBase;
import com.kadron.enumeration.Gender;
import com.kadron.enumeration.KLang;
import com.kadron.enumeration.UserStatus;
import com.kadron.enumeration.UserType;

@Entity
@Table(name = "k_user", uniqueConstraints = { 
		@UniqueConstraint(columnNames = {"email"}),
		@UniqueConstraint(columnNames = {"ordinal"}),
		@UniqueConstraint(columnNames = {"username"}) })
public class User extends KVBase implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2837372315348955126L;
	
	private String username;
	private String password;
	private String email;

	private String nickname;
	private String firstname;
	private String lastname;
	private String address;
	
	private String tel;
	private String mob;
	
	private Date birthday;
	private KLang lang = KLang.EN;
	
	private String desc;
	
	private boolean newsletter;
	
	private boolean nameVisible;
	private boolean emailVisible;
	private boolean birthdayVisible;
	private boolean telVisible;
	
	private UserType userType = UserType.STANDARD;
	
	private boolean admin;
	private boolean blocked;
	private Currency currency;
	private boolean alarm;
	private boolean acceptedTerms;
	private UserStatus userStatus = UserStatus.SIGNED_UP;
	private Gender gender = Gender.MALE;
	private Date regDate;
	private Date statusUpdate;
	
	private long ordinal;
	
	public User() {
		super();
	}

	public User(String username, String password, String email,
			String nickname, String firstname, String lastname, String address,
			String tel, String mob, Date birthday, KLang lang, String desc,
			boolean newsletter, boolean nameVisible, boolean emailVisible,
			boolean birthdayVisible, boolean telVisible, Gender gender) {
		super();
		this.username = username;
		this.password = password;
		this.email = email;
		this.nickname = nickname;
		this.firstname = firstname;
		this.lastname = lastname;
		this.address = address;
		this.tel = tel;
		this.mob = mob;
		this.birthday = birthday;
		this.lang = lang;
		this.desc = desc;
		this.newsletter = newsletter;
		this.nameVisible = nameVisible;
		this.emailVisible = emailVisible;
		this.birthdayVisible = birthdayVisible;
		this.telVisible = telVisible;
		this.gender = gender;
	}

	@NotNull
	@Column(name = "username", nullable = false)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@NotNull
	@Column(name = "password", nullable = false)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Column(name = "email", nullable = false)
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Column(name = "nickname", nullable = false)
	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	@Column(name = "firstname", nullable = false)
	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	@Column(name = "lastname", nullable = false)
	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	@Column(name = "address")
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Column(name = "tel", nullable = false)
	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	@Column(name = "mob", nullable = false)
	public String getMob() {
		return mob;
	}

	public void setMob(String mob) {
		this.mob = mob;
	}

	@Column(name = "birthday", nullable = false)
	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Column(name = "lang")
	public KLang getLang() {
		return lang;
	}

	public void setLang(KLang lang) {
		this.lang = lang;
	}

	@Column(name = "description", columnDefinition = "TEXT")
	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	@Column(name = "newsletter")
	public boolean isNewsletter() {
		return newsletter;
	}

	public void setNewsletter(boolean newsletter) {
		this.newsletter = newsletter;
	}

	@Column(name = "name_visible")
	public boolean isNameVisible() {
		return nameVisible;
	}

	public void setNameVisible(boolean nameVisible) {
		this.nameVisible = nameVisible;
	}

	@Column(name = "email_visible")
	public boolean isEmailVisible() {
		return emailVisible;
	}

	public void setEmailVisible(boolean emailVisible) {
		this.emailVisible = emailVisible;
	}

	@Column(name = "birthday_visible")
	public boolean isBirthdayVisible() {
		return birthdayVisible;
	}

	public void setBirthdayVisible(boolean birthdayVisible) {
		this.birthdayVisible = birthdayVisible;
	}

	@Column(name = "tel_visible")
	public boolean isTelVisible() {
		return telVisible;
	}

	public void setTelVisible(boolean telVisible) {
		this.telVisible = telVisible;
	}

	@Column(name = "user_type", nullable = false)
	public UserType getUserType() {
		return userType;
	}
	
	public void setUserType(UserType userType) {
		this.userType = userType;
	}

	@Column(name = "admin")
	public boolean isAdmin() {
		return admin;
	}

	public void setAdmin(boolean admin) {
		this.admin = admin;
	}

	@Column(name = "blocked")
	public boolean isBlocked() {
		return blocked;
	}

	public void setBlocked(boolean blocked) {
		this.blocked = blocked;
	}
	
	@Column(name = "alarm")
	public boolean isAlarm() {
		return alarm;
	}
	
	public void setAlarm(boolean alarm) {
		this.alarm = alarm;
	}
	
	@Transient
	public Currency getCurrency() {
		return currency;
	}

	public void setCurrency(Currency currency) {
		this.currency = currency;
	}

	@Column(name = "accepted_terms", nullable = false)
	public boolean isAcceptedTerms() {
		return acceptedTerms;
	}

	public void setAcceptedTerms(boolean acceptedTerms) {
		this.acceptedTerms = acceptedTerms;
	}

	@Column(name = "user_status", nullable = false)
	public UserStatus getUserStatus() {
		return userStatus;
	}

	public void setUserStatus(UserStatus userStatus) {
		this.userStatus = userStatus;
	}
	
	@Column(name = "gender", nullable = false, length = 1)
	public Gender getGender() {
		return gender;
	}
	
	public void setGender(Gender gender) {
		this.gender = gender;
	}
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "reg_date")
	public Date getRegDate() {
		return regDate;
	}

	public void setRegDate(Date regDate) {
		this.regDate = regDate;
	}

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "status_update")
	public Date getStatusUpdate() {
		return statusUpdate;
	}

	public void setStatusUpdate(Date statusUpdate) {
		this.statusUpdate = statusUpdate;
	}
	
	@Column(name = "ordinal", nullable = false, updatable = false)
	public long getOrdinal() {
		return ordinal;
	}

	public void setOrdinal(long ordinal) {
		this.ordinal = ordinal;
	}

	@Transient
	public void updateData(AccountData data) {
//		this.username = data.getUsername();
//		this.email = data.getEmail();
		this.nickname = data.getNickname();
		this.firstname = data.getFirstname();
		this.lastname = data.getLastname();
		this.address = data.getAddress();
		this.tel = data.getTel();
		this.mob = data.getMob();
		this.birthday = data.getBirthday();
		this.lang = data.getLang();
		this.desc = data.getDesc();
		this.newsletter = data.isNewsletter();
		this.nameVisible = data.isNameVisible();
		this.emailVisible = data.isEmailVisible();
		this.birthdayVisible = data.isBirthdayVisible();
		this.telVisible = data.isTelVisible();
		this.gender = data.getGender();
	}
	
	@Transient
	public String getFullName() {
		return firstname + " " + lastname;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + (int) (getId() ^ (getId() >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (getId() != other.getId())
			return false;
		return true;
	}

}